package com.etcbase.dcs.controller.map;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;

import android.animation.Animator;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.etcbase.dcs.DcsApp;
import com.etcbase.dcs.R;
import com.etcbase.dcs.controller.map.MapLocationAsyncTask.OnGetLocationAddressListener;
import com.etcbase.dcs.controller.map.MapMarkersOverlay.OnTapListener;
import com.etcbase.dcs.controller.map.MapNoteListAsyncTask.OnGetItemsListener;
import com.etcbase.dcs.model.map.MapNote;
import com.etcbase.dcs.utils.gui.LayoutHeightAnimator;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;

public class MapNavigationActivity extends MapActivity implements
		OnClickListener {
	public final static String TAG = MapNavigationActivity.class
			.getSimpleName();

	private LinearLayout linearLayoutMain;
	private RelativeLayout relativeLayoutTopMenu;
	private RelativeLayout relativeLayoutBottomMap;
	private LayoutHeightAnimator layoutHeightTopMenuAnimator;
	private LayoutHeightAnimator layoutHeightBottomMapAnimator;

	private final static int DISPLAY_TOP = 0;
	private final static int DISPLAY_BOTTOM = 1;
	private final static int DISPLAY_BOTH = 2;
	private int currentDisplayState = DISPLAY_BOTH;

	// INPUT FIELDS
	private Spinner citySpinner;
	private Spinner districtSpinner;
	private EditText editTextName;
	private EditText editTextNote;
	private ListView listView;

	// DATABASE
	private MapView mapView;
	private ArrayList<MapNote> mapNoteList;
	private int mapNoteSelectedIndex = -1;
	private MapNote mapNoteSearch = new MapNote();
	private MapNote mapNoteData = new MapNote();

	// MAP
	private MapController mapController;
	private MyLocationOverlay myLocationOverlay; // GOOGLE-MAPS API
	private MapSelectedLocationOverlay selectedLocationOverlay;
	private MapMarkersOverlay mapMarkersOverlay;
	LinearLayout linearLayoutInfoBox;

	// LOCATION
	private GeoPoint currentLocation;
	private LocationManager locationManager;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.map_panel);

		initLayouts();
		initSpinners();
		initButtons();
		initListView();

		// initialize the MAP-CONTROLS
		mapView = (MapView) findViewById(R.id.mapView);
		mapView.setBuiltInZoomControls(true);

		mapController = mapView.getController();
		mapController.setZoom(14);

		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, new GeoUpdateHandler());

		// my-location overlay
		myLocationOverlay = new MyLocationOverlay(this, mapView);
		myLocationOverlay.enableMyLocation();
		myLocationOverlay.runOnFirstFix(new Runnable() {
			public void run() {
				mapView.getController().animateTo(
						myLocationOverlay.getMyLocation());
			}
		});
		mapView.getOverlays().add(myLocationOverlay);

		// marker overlay
		Drawable blueMarker = this.getResources().getDrawable(
				R.drawable.map_marker_blue);
		selectedLocationOverlay = new MapSelectedLocationOverlay(blueMarker);
		mapView.getOverlays().add(selectedLocationOverlay);

		// Drawable redMarker =
		// this.getResources().getDrawable(R.drawable.map_marker_red);
		// Drawable greenMarker =
		// this.getResources().getDrawable(R.drawable.map_marker_green);
		// Drawable invisibleMarker =
		// this.getResources().getDrawable(R.drawable.map_marker_invisible);
		// mMarkersOverlay = new MarkersOverlay( redMarker, greenMarker,
		// invisibleMarker );
		// mMapView.getOverlays().add(mMarkersOverlay);

		// INFO-BOX on the MAP-VIEW
		linearLayoutInfoBox = (LinearLayout) findViewById(R.id.mapLinearLayoutInfoBox);
		linearLayoutInfoBox.setVisibility(LinearLayout.INVISIBLE);
		linearLayoutInfoBox.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Animation mFadeOutAnimation = AnimationUtils.loadAnimation(
						MapNavigationActivity.this, R.anim.fade_out);
				mFadeOutAnimation.setAnimationListener(new AnimationListener() {
					@Override
					public void onAnimationStart(Animation animation) {
					}

					@Override
					public void onAnimationRepeat(Animation animation) {
					}

					@Override
					public void onAnimationEnd(Animation animation) {
						linearLayoutInfoBox
								.setVisibility(LinearLayout.INVISIBLE);
					}
				});
				linearLayoutInfoBox.startAnimation(mFadeOutAnimation);
			}
		});

		updateListView(false); // false means: populate the map but do not
								// animate to the container region
	}

	@Override
	protected void onResume() {
		super.onResume();
		// Location location = mLocationManager.getLastKnownLocation(
		// LocationManager.GPS_PROVIDER );
		// int lat = (int) (location.getLatitude()*1E6);
		// int lng = (int) (location.getLongitude()*1E6);
		// mCurrentLocation = new GeoPoint(lat, lng);
		// mMapController.animateTo(mCurrentLocation);
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
	}

	private void initLayouts() {
		int durationTime = 500;
		linearLayoutMain = (LinearLayout) findViewById(R.id.mapLinearLayoutMain);
		relativeLayoutTopMenu = (RelativeLayout) findViewById(R.id.mapRelativeLayoutTopMenu);
		relativeLayoutBottomMap = (RelativeLayout) findViewById(R.id.mapRelativeLayoutBottomMap);

		layoutHeightTopMenuAnimator = new LayoutHeightAnimator(
				relativeLayoutTopMenu, durationTime);
		layoutHeightBottomMapAnimator = new LayoutHeightAnimator(
				relativeLayoutBottomMap, durationTime);

		// MAP - BUTTON
		findViewById(R.id.mapButtonShowHideMap).setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						switch (currentDisplayState) {
						case DISPLAY_TOP:
							setDisplayState(DISPLAY_BOTH);
							break;

						case DISPLAY_BOTH:
							setDisplayState(DISPLAY_BOTTOM);
							break;
						}
					}
				});

		// MENU - BUTTON
		findViewById(R.id.mapButtonShowHideMenu).setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						switch (currentDisplayState) {
						case DISPLAY_BOTTOM:
							setDisplayState(DISPLAY_BOTH);
							break;

						case DISPLAY_BOTH:
							setDisplayState(DISPLAY_TOP);
							break;
						}
					}
				});

		// HIDE / SHOW SEARCH GROUP-VIEW
		findViewById(R.id.mapImageButtonHideSearch).setOnClickListener(
				new OnClickListener() {
					ViewGroup layoutViewGroup = (ViewGroup) findViewById(R.id.mapRelativeLayoutGroupSearch);
					LayoutHeightAnimator layoutHeightAnimator = new LayoutHeightAnimator(
							layoutViewGroup, 300);
					android.animation.Animator.AnimatorListener listener = new android.animation.Animator.AnimatorListener() {
						@Override
						public void onAnimationCancel(Animator arg0) {
						}

						@Override
						public void onAnimationEnd(Animator arg0) {
						}

						@Override
						public void onAnimationRepeat(Animator arg0) {
						}

						@Override
						public void onAnimationStart(Animator arg0) {
						}
					};

					@Override
					public void onClick(View v) {
						LayoutParams layoutParams = layoutViewGroup
								.getLayoutParams();
						if (layoutParams.height > 0) {
							layoutHeightAnimator.start(0, listener);
						} else {
							int height = getResources()
									.getDimensionPixelOffset(
											R.dimen.mapRelativeLayoutGroupSearchHeight);
							layoutHeightAnimator.start(height, listener);
						}
					}
				});

	}

	private void initSpinners() {
		citySpinner = (Spinner) findViewById(R.id.mapSpinnerCity);
		districtSpinner = (Spinner) findViewById(R.id.mapSpinnerDistrict);
		setupSpinners(citySpinner, districtSpinner);
	}

	private void initButtons() {
		// TOP
		editTextName = (EditText) findViewById(R.id.mapEditTextName);
		editTextName.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View view) {
				((EditText) view).setText("");
				return true;
			}
		});
		editTextNote = (EditText) findViewById(R.id.mapEditTextNote);
		editTextNote.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View view) {
				((EditText) view).setText("");
				return true;
			}
		});
		//
		findViewById(R.id.mapButtonSearch).setOnClickListener(this);
		findViewById(R.id.mapButtonClear).setOnClickListener(this);
		findViewById(R.id.mapButtonSave).setOnClickListener(this);
		findViewById(R.id.mapButtonUpdate).setOnClickListener(this);
		findViewById(R.id.mapButtonDelete).setOnClickListener(this);

		// BOTTOM-MAP
		findViewById(R.id.map_button_selectCurrentLocation).setOnClickListener(
				this);
	}

	private void initListView() {
		listView = (ListView) findViewById(R.id.mapListView);
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> listView, View rowView,
					int index, long id) {
				MapNote item = mapNoteList.get(index);

				if (item == null) {
					mapNoteSelectedIndex = -1;
				} else {
					mapNoteSelectedIndex = index;

					// Log.d( TAG, "id = " + item.getID() );
					// Log.d( TAG, "index = " + index );

					// "index + 1" because there is 1 redundant overlay-item in
					// the markers-overlay to avoid crash in 4.0.3
					mapMarkersOverlay.setSelectedOverlayItem(index + 1);
					mapView.invalidate();
					mapController.animateTo(item.getGeoPoint());
				}
			}
		});
	}

	private void setArrayAdapter(ArrayList<HashMap<String, String>> data) {
		int[] to = new int[] { R.id.map_list_item_text1,
				R.id.map_list_item_text2, R.id.map_list_item_text3,
				R.id.map_list_item_text4, R.id.map_list_item_text5,
				R.id.map_list_item_text6, R.id.map_list_item_text7,
				R.id.map_list_item_text8, R.id.map_list_item_text9, };

		String[] from = new String[] { MapNoteDao.ITEM_USER_NAME,
				MapNoteDao.ITEM_NAME, MapNoteDao.ITEM_CITY,
				MapNoteDao.ITEM_DISTRICT, MapNoteDao.ITEM_ADDRESS,
				MapNoteDao.ITEM_LATITUDE, MapNoteDao.ITEM_LONGITUDE,
				MapNoteDao.ITEM_NOTE, MapNoteDao.ITEM_EDIT_DATE };

		// ArrayList<HashMap<String,String>> data = new
		// ArrayList<HashMap<String,String>>();
		SimpleAdapter adapter = new SimpleAdapter(this, data,
				R.layout.map_list_item, from, to);
		ListView listView = (ListView) findViewById(R.id.mapListView);
		listView.setAdapter(adapter);
	}

	private void updateListView(final boolean animateMap) {
		mapNoteSelectedIndex = -1;
		MapNoteListAsyncTask task = new MapNoteListAsyncTask(getDcsApp()
				.getMapNoteViewDataBaseConnector(), mapNoteSearch);
		task.setOnGetItemsListener(new OnGetItemsListener() {
			@Override
			public void onGetItems(Cursor result) {
				mapNoteList = new ArrayList<MapNote>();
				ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();

				if (result.getCount() > 0) {
					result.moveToFirst();
					do {
						MapNote item = MapNoteDao.getItem(result);
						mapNoteList.add(item);

						HashMap<String, String> map = MapNoteDao.getMap(result);
						data.add(map);
					} while (result.moveToNext());
				}

				// pad the list to 10 items
				int numItems = 10;
				while (data.size() <= numItems) {
					mapNoteList.add(null); // no item here!

					HashMap<String, String> map = new HashMap<String, String>();
					for (String field : MapNoteDao.ITEM_FIELDS) {
						map.put(field, "");
					}
					data.add(map);
				}
				setArrayAdapter(data);

				repopulateWithSavedLocationMarkers(animateMap);
			}
		});
		task.execute((Object[]) null);
	}

	private void repopulateWithSavedLocationMarkers(boolean animateMap) {
		//
		if (mapMarkersOverlay == null) {
			Drawable redMarker = this.getResources().getDrawable(
					R.drawable.map_marker_red);
			Drawable greenMarker = this.getResources().getDrawable(
					R.drawable.map_marker_green);
			Drawable invisibleMarker = this.getResources().getDrawable(
					R.drawable.map_marker_invisible);
			mapMarkersOverlay = new MapMarkersOverlay(redMarker, greenMarker,
					invisibleMarker);
			mapMarkersOverlay.setOnTapListener(new OnTapListener() {
				@Override
				public void onTap(int index) {
					// if the item is selected, this also means that it is a
					// valid item
					if (mapMarkersOverlay.setSelectedOverlayItem(index)) {
						TextView textViewName = (TextView) findViewById(R.id.mapInfoBoxTextViewName);
						TextView textViewNote = (TextView) findViewById(R.id.mapInfoBoxTextViewNote);
						OverlayItem selectedOverlayItem = mapMarkersOverlay
								.getSelectedOverlayItem();
						textViewName.setText(selectedOverlayItem.getTitle());
						textViewNote.setText(selectedOverlayItem.getSnippet());
						linearLayoutInfoBox.setVisibility(LinearLayout.VISIBLE);
					}
				}
			});
			mapView.getOverlays().add(mapMarkersOverlay);
		} else {
			mapMarkersOverlay.freeAllSavedLocationMarkers();
		}

		final double a = 400.0;
		double maxLat = -a, maxLng = -a;
		double minLat = a, minLng = a;
		int numValid = 0;
		GeoPoint pmax = null;
		for (MapNote item : mapNoteList) {
			if (item != null) {
				numValid++;
				double lat = Double.parseDouble(item.getLatitude());
				double lng = Double.parseDouble(item.getLongitude());

				GeoPoint p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
				mapMarkersOverlay.addSavedLocationMarker(p, item.getName(),
						item.getNote());

				if (minLat > lat)
					minLat = lat;
				if (maxLat < lat)
					maxLat = lat;

				if (minLng > lng)
					minLng = lng;
				if (maxLng < lng)
					maxLng = lng;
			}
		}

		// if no map-update is requested -> skip the following steps
		if (!animateMap) {
			mapView.invalidate();
			return;
		}

		if (numValid > 0) {
			double midLat = (minLat + maxLat) / 2;
			double midLng = (minLng + maxLng) / 2;
			midLat *= 1E6;
			midLng *= 1E6;
			int spanLat = (int) ((maxLat - minLat) * 1E6);
			int spanLng = (int) ((maxLng - minLng) * 1E6);
			mapController.animateTo(new GeoPoint((int) midLat, (int) midLng));
			mapController.zoomToSpan(spanLat, spanLng);
		}
		mapView.invalidate();
	}

	// functions in this class are called when location updates occur
	public class GeoUpdateHandler implements LocationListener {
		@Override
		public void onLocationChanged(Location location) {
			int lat = (int) (location.getLatitude() * 1E6);
			int lng = (int) (location.getLongitude() * 1E6);
			currentLocation = new GeoPoint(lat, lng);
			// mMapController.animateTo(mCurrentLocation);
		}

		@Override
		public void onProviderDisabled(String arg0) {
		}

		@Override
		public void onProviderEnabled(String arg0) {
		}

		@Override
		public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		}
	}

	private void setupSpinners(Spinner spinner_city, Spinner spinner_district) {
		setupSpinners(spinner_city, spinner_district, -1, -1);
	}

	private void setupSpinners(Spinner spinner_city,
			final Spinner spinner_district, int firstCity,
			final int firstDistrict) {
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item, getDcsApp()
						.getAddressResolver().getCityList());

		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spinner_city.setAdapter(adapter);
		spinner_city.setOnItemSelectedListener(new OnItemSelectedListener() {
			int mFirstDistrict = firstDistrict;

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					final int arg2, long arg3) {
				// fill the district-spinner accordingly
				String selectedCity = getDcsApp().getAddressResolver()
						.getCityList().get(arg2);
				ArrayList<String> districts = getDcsApp().getAddressResolver()
						.getDistricts(selectedCity);
				// if there is not districts (this happens when "Select" is
				// selected )
				if (districts == null) {
					// define a dummy select array / DISABLE DISTRICTS SPINNER?
					districts = new ArrayList<String>();
					districts.add(getResources().getString(R.string.SPINNER_SELECT));
				}

				final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
						MapNavigationActivity.this,
						android.R.layout.simple_spinner_item, districts);
				adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
				spinner_district.setAdapter(adapter);
				if (mFirstDistrict >= 0) {
					spinner_district.setSelection(firstDistrict);
					mFirstDistrict = -1;
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
			}
		});
		if (firstCity >= 0) {
			spinner_city.setSelection(firstCity);
		}
	}

	private void setDisplayState(int displayState) {
		int totalHeight = linearLayoutMain.getHeight();

		switch (displayState) {
		case DISPLAY_TOP:
			layoutHeightTopMenuAnimator.start(totalHeight - 1, null);
			layoutHeightBottomMapAnimator.start(1, null);
			break;

		case DISPLAY_BOTTOM:
			layoutHeightTopMenuAnimator.start(1, null);
			layoutHeightBottomMapAnimator.start(totalHeight - 1, null);
			break;

		case DISPLAY_BOTH:
			int halfHeight = totalHeight / 2;
			layoutHeightTopMenuAnimator.start(halfHeight, null);
			layoutHeightBottomMapAnimator.start(totalHeight - halfHeight, null);
			break;
		}
		currentDisplayState = displayState;
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {

		case R.id.mapButtonSearch:
			search();
			break;

		case R.id.mapButtonClear:
			clear();
			break;

		case R.id.mapButtonSave:
			add();
			break;

		case R.id.mapButtonDelete:
			delete();
			break;

		case R.id.mapButtonUpdate:
			update();
			break;

		case R.id.map_button_selectCurrentLocation:
			selectCurrentLocation();
			break;
		}
	}

	private void search() {

		if (citySpinner.getSelectedItemPosition() == 0) {
			mapNoteSearch.setCity(null);
		} else {
			String city = (String) citySpinner.getSelectedItem();
			mapNoteSearch.setCity(city);
		}

		if (districtSpinner.getSelectedItemPosition() == 0) {
			mapNoteSearch.setDistrict(null);
		} else {
			mapNoteSearch.setDistrict((String) districtSpinner
					.getSelectedItem());
		}

		mapNoteSearch.setName(editTextName.getText().toString());
		mapNoteSearch.setNote(editTextNote.getText().toString());

		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(editTextName.getWindowToken(), 0);
		imm.hideSoftInputFromWindow(editTextNote.getWindowToken(), 0);

		// TODO: set user name?
		updateListView(true);
	}

	private void clear() {
		editTextName.setText("");
		editTextNote.setText("");
		citySpinner.setSelection(0);
		districtSpinner.setSelection(0);
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(editTextName.getWindowToken(), 0);
		imm.hideSoftInputFromWindow(editTextNote.getWindowToken(), 0);
	}

	private void add() {
		GeoPoint p = selectedLocationOverlay.getSelectedLocation();
		mapNoteData.setLatLong(p);

		// schedule an async-task to get address of the selected location
		// when asynch-task is finished, write it to the database
		showToast(getResources().getString(R.string.MAP_PANEL_RETRIEVING_ADDRESS_TOAST));
		MapLocationAsyncTask task = new MapLocationAsyncTask();
		task.setOnGetLocationAddressListener(new OnGetLocationAddressListener() {
			@Override
			public void onGetLocationAddress(String city, String district,
					String address) {
				String correctCity = getDcsApp().getAddressResolver()
						.getCorrectCityName(city);
				String correctDistrict = getDcsApp().getAddressResolver()
						.getCorrectDistrictName(correctCity, district);
				mapNoteData.setCity(correctCity);
				mapNoteData.setDistrict(correctDistrict);
				mapNoteData.setAddress(address);

				int cityIndex = getDcsApp().getAddressResolver().getCityIndex(
						correctCity);
				int districtIndex = getDcsApp().getAddressResolver()
						.getDistrictIndex(correctCity, correctDistrict);

				// OPEN A DIALOG WINDOW IN ADD-MODE
				final AddUpdateItemDialog dialog = new AddUpdateItemDialog(
						MapNavigationActivity.this, cityIndex, districtIndex);

				TextView addressView = (TextView) dialog
						.findViewById(R.id.map_dialog_add_textView_address);
				addressView.setText(mapNoteData.getAddress());

				// set title
				TextView textView_title = (TextView) dialog
						.findViewById(R.id.map_dialog_add_textView_title);
				textView_title.setText(getResources().getString(
						R.string.MAP_NOTE_ADD_UPDATE_PANEL_ADD_ITEM_TEXT_VIEW));

				// set button name to "ADD"
				Button button_save = (Button) dialog
						.findViewById(R.id.map_dialog_add_button_save);
				button_save.setText(getResources().getString(R.string.MAP_PANEL_ADD_BUTTON));
				Button button_cancel = (Button) dialog
						.findViewById(R.id.map_dialog_add_button_cancel);
				button_cancel.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						showToast(getResources().getString(
								R.string.MAP_PANEL_TOAST_ADD_CANCELLED));
						dialog.dismiss();
					}
				});
				// when OK button is clicked the following will take place
				button_save.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {

						// check if the fields have been selected
						Spinner spinner_city = dialog.getSpinnerCity();
						Spinner spinner_district = dialog.getSpinnerDistrict();
						if (spinner_city.getSelectedItemPosition() == 0) {
							showToast(getResources().getString(
									R.string.MAP_PANEL_TOAST_SELECT_CITY));
							return;
						}
						if (spinner_district.getSelectedItemPosition() == 0) {
							showToast(getResources().getString(
									R.string.MAP_PANEL_TOAST_SELECT_DISTRICT));
							return;
						}
						mapNoteData.setCity((String) spinner_city
								.getSelectedItem());
						mapNoteData.setDistrict((String) spinner_district
								.getSelectedItem());

						EditText editTextName = (EditText) dialog
								.findViewById(R.id.mapDialogAddEditTextName);
						EditText editTextNote = (EditText) dialog
								.findViewById(R.id.mapDialoAddEditTextNote);
						mapNoteData.setUserName(getDcsApp().getUserName());
						mapNoteData.setName(editTextName.getText().toString());
						mapNoteData.setNote(editTextNote.getText().toString());
						mapNoteData.setEditDate(Calendar.getInstance());

						// TODO: do this update in an AsyncTask?
						MapNoteDao mapNoteDao = getDcsApp()
								.getMapNoteViewDataBaseConnector();
						mapNoteDao.openForWrite();
						mapNoteDao.insert(mapNoteData);
						mapNoteDao.close();

						showToast(getResources().getString(R.string.MAP_PANEL_TOAST_ITEM_ADDED));
						updateListView(true);

						dialog.dismiss();
					}
				});
				dialog.show();
			}
		});

		// finally execute the address retrieval as an AsychTask
		task.execute(p);
	}

	private void update() {
		if (mapNoteSelectedIndex == -1) {
			showToast(getResources().getString(R.string.MAP_PANEL_TOAST_NO_ITEM_SELECTED));
			return;
		}

		// get the selected item data
		mapNoteData = mapNoteList.get(mapNoteSelectedIndex);
		String city = mapNoteData.getCity();
		String district = mapNoteData.getDistrict();
		int cityIndex = getDcsApp().getAddressResolver().getCityIndex(city);
		int districtIndex = getDcsApp().getAddressResolver().getDistrictIndex(
				city, district);

		// DIALOG FOR ADDING ITEM
		final AddUpdateItemDialog dialog = new AddUpdateItemDialog(
				MapNavigationActivity.this, cityIndex, districtIndex);

		// set title
		TextView textView_title = (TextView) dialog
				.findViewById(R.id.map_dialog_add_textView_title);
		textView_title.setText(getResources().getString(R.string.MAP_NOTE_ADD_UPDATE_PANEL_UPDATE_ITEM_TEXT_VIEW));

		// set button name to "UPDATE"
		Button button_save = (Button) dialog
				.findViewById(R.id.map_dialog_add_button_save);
		button_save.setText(getResources().getString(R.string.MAP_PANEL_UPDATE_BUTTON));

		Button button_cancel = (Button) dialog
				.findViewById(R.id.map_dialog_add_button_cancel);
		button_cancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				showToast(getResources().getString(R.string.MAP_PANEL_TOAST_UPDATE_CANCELLED));
				dialog.dismiss();
			}
		});

		// initialize
		EditText editText_name = (EditText) dialog
				.findViewById(R.id.mapDialogAddEditTextName);
		EditText editText_note = (EditText) dialog
				.findViewById(R.id.mapDialoAddEditTextNote);
		TextView textView_address = (TextView) dialog
				.findViewById(R.id.map_dialog_add_textView_address);
		editText_name.setText(mapNoteData.getName());
		editText_note.setText(mapNoteData.getNote());
		textView_address.setText(mapNoteData.getAddress());

		// dialog.getSpinnerCity().setSelection( cityIndex );
		// dialog.getSpinnerDistrict().setSelection( districtIndex );

		// when OK button is clicked the following will take place
		button_save.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				EditText editTextName = (EditText) dialog
						.findViewById(R.id.mapDialogAddEditTextName);
				EditText editTextNote = (EditText) dialog
						.findViewById(R.id.mapDialoAddEditTextNote);
				String name = editTextName.getText().toString();
				String note = editTextNote.getText().toString();
				mapNoteData.setName(name);
				mapNoteData.setNote(note);
				mapNoteData.setEditDate(Calendar.getInstance());

				Log.d(TAG, "item-note: " + note);
				Log.d(TAG, "item-name: " + name);

				// TODO: do this update in an AsyncTask?
				MapNoteDao mapNoteDao = getDcsApp()
						.getMapNoteViewDataBaseConnector();
				mapNoteDao.openForWrite();
				mapNoteDao.update(mapNoteData);
				mapNoteDao.close();

				showToast(getResources().getString(R.string.MAP_PANEL_TOAST_ITEM_UPDATED));
				updateListView(true);

				dialog.dismiss();
			}
		});

		dialog.show();
	}

	private void delete() {
		if (mapNoteSelectedIndex == -1) {
			showToast(getResources().getString(R.string.MAP_PANEL_TOAST_NO_ITEM_SELECTED));
			return;
		}

		// get the selected item
		mapNoteData = mapNoteList.get(mapNoteSelectedIndex);

		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(
				getResources().getString(R.string.MAP_PANEL_DIALOG_QUESTION_DELETE_ITEM))
				.setCancelable(false)
				.setPositiveButton(getResources().getString(R.string.MAP_PANEL_OK_BUTTON),
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								MapNoteDao dbc = getDcsApp()
										.getMapNoteViewDataBaseConnector();
								dbc.delete(mapNoteData);
								updateListView(true);
								showToast(getResources().getString(
										R.string.MAP_PANEL_TOAST_ITEM_DELETED));
							}
						})
				.setNegativeButton("No", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						// showToast("NO CLICKED");
					}
				});
		AlertDialog alert = builder.create();
		alert.show();
	}

	private void selectCurrentLocation() {
		showToast(getResources().getString(R.string.MAP_PANEL_TOAST_CURRENT_LOCATION_SELECTED));
		if (myLocationOverlay.getMyLocation() != null) {
			currentLocation = myLocationOverlay.getMyLocation();
		}
		if (currentLocation != null) {
			selectedLocationOverlay.setSelectedLocation(currentLocation);
			mapController.animateTo(currentLocation);
		}
	}

	private DcsApp getDcsApp() {
		return (DcsApp) getApplication();
	}

	private void showToast(String text) {
		Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
	}

	private void showToastLong(String text) {
		Toast.makeText(this, text, Toast.LENGTH_LONG).show();
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	class AddUpdateItemDialog extends Dialog {

		private Spinner citySpinner;
		private Spinner districtSpinner;

		public AddUpdateItemDialog(Context context) {
			this(context, -1, -1);
		}

		public AddUpdateItemDialog(Context context, int firstCity,
				int firstDistrict) {
			super(context, R.style.map_dialog_addItem);
			setContentView(R.layout.map_note_insert_update_panel);
			setCancelable(true);

			// set-up spinners
			citySpinner = (Spinner) this
					.findViewById(R.id.map_dialog_add_spinner_city);
			districtSpinner = (Spinner) this
					.findViewById(R.id.map_dialog_add_spinner_district);
			setupSpinners(citySpinner, districtSpinner, firstCity,
					firstDistrict);
		}

		public Spinner getSpinnerCity() {
			return citySpinner;
		}

		public Spinner getSpinnerDistrict() {
			return districtSpinner;
		}
	}
}
